package cn.dinkevin.xui.net;

import com.facebook.stetho.okhttp3.StethoInterceptor;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import cn.dinkevin.xui.BuildConfig;
import cn.dinkevin.xui.XUI;
import cn.dinkevin.xui.net.converter.ApiErrorConverterFactory;
import cn.dinkevin.xui.net.converter.EmptyJsonConverterFactory;
import cn.dinkevin.xui.net.converter.GsonConverterFactory;
import cn.dinkevin.xui.util.ListUtil;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

/**
 * Create with Intellij IDEA
 * Author: chengpengfei
 * Date: 2018/4/26 3:00 PM
 * Description: 网络服务
 */
public class RetrofitService {

    private static final int CONNECT_TIMEOUT = 30;
    private static final int READ_TIMEOUT = 30;
    private static final int WRITE_TIMEOUT = 30;
    private static final int CACHE_SIZE = 1024 * 1024 * 20;

    private static volatile RetrofitService sInstance = null;
    private static String mHost;
    private static List<Interceptor> mInterceptors = new ArrayList<>();

    private Retrofit mRetrofit;

    private RetrofitService(boolean useRxJava,String host) {
        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(host)
                .addConverterFactory(new ApiErrorConverterFactory(EmptyJsonConverterFactory.create(GsonConverterFactory.create())))
                .client(getOkHttpClient());

        if (useRxJava) {
            builder.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()));
        }

        mRetrofit = builder.build();
    }


    /**
     * 初始化
     * @param host              主机地址
     * @param interceptors      网络请求拦截器
     */
    public static void initial(String host, List<Interceptor> interceptors){

        mHost = host;
        mInterceptors.clear();
        ListUtil.addAll(mInterceptors,interceptors);

        getInstance();
    }


    /**
     * 初始化
     * @param host              主机地址
     */
    public static void initial(String host){
        initial(host,null);
    }


    /**
     * 只有首次调用才起效
     * @return
     */
    public static RetrofitService getInstance() {
        if (sInstance == null) {
            synchronized (RetrofitService.class) {
                if (sInstance == null) {
                    sInstance = new RetrofitService(true,mHost);
                }
            }
        }
        return sInstance;
    }

    private OkHttpClient getOkHttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.cache(new Cache(XUI.getInstance().getContext().getCacheDir(), CACHE_SIZE))
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .followRedirects(true)
                .hostnameVerifier((hostname, session) -> true);
        ListUtil.foreach(mInterceptors,interceptor -> builder.addInterceptor(interceptor));

        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);
        builder.addInterceptor(loggingInterceptor);
        if (BuildConfig.DEBUG) {
            builder.addNetworkInterceptor(new StethoInterceptor());
        }

        return builder.build();
    }

    public <T> T createService(Class<T> service) {
        return mRetrofit.create(service);
    }
}
